import sqlite3
from boot import DB_ROOT_DIR, List, Dict


__all__ = [
    "DBBase",
    "commit",
    "get_one_value",
    "get_one_dict",
    "get_all_dict",
]


def commit(method):
    def wrapper(self, *args, **kwargs):
        sql = method(self, *args, **kwargs)
        field_names = list(kwargs.keys())
        if len(field_names):
            value_list = [kwargs[field_name] for field_name in field_names]
        else:
            value_list = args
        self.cursor.execute(sql, tuple(value_list))
        self.conn.commit()
        return self
    return wrapper


def get_one_value(method):
    def wrapper(self, *args, **kwargs):
        sql = method(self, *args, **kwargs)
        field_names = kwargs.keys()
        if len(field_names):
            value_list = [kwargs[field_name] for field_name in field_names]
        else:
            value_list = args
        self.cursor.execute(sql, tuple(value_list))
        return self.cursor.fetchone()[0]
    return wrapper


def get_one_dict(table_name):
    def wrapper(method):
        def inner(self, *args, **kwargs):
            sql = method(self, *args, **kwargs)

            field_names = kwargs.keys()
            if len(field_names):
                value_list = [kwargs[field_name] for field_name in field_names]
            else:
                value_list = args

            self.cursor.execute(f"PRAGMA table_info({table_name});")
            field_names_list = [i[1] for i in self.cursor.fetchall()]

            self.cursor.execute(sql, tuple(value_list))
            result_list = self.cursor.fetchone()

            return dict(zip(field_names_list, result_list))
        return inner
    return wrapper


def get_all_dict(table_name):
    def wrapper(method):
        def inner(self, *args, **kwargs):
            # 1.获取sql
            sql = method(self, *args, **kwargs)
            if sql is None or sql == "":
                sql = f"SELECT * FROM `{table_name}`;"

            # 2.获取实参
            field_names = kwargs.keys()
            if len(field_names):
                value_list = [kwargs[field_name] for field_name in field_names]
            else:
                value_list = args

            # 3.获取字段列表
            self.cursor.execute(f"PRAGMA table_info({table_name});")
            field_names_list = [i[1] for i in self.cursor.fetchall()]

            # 4.运行参数获取结果
            if len(value_list):
                if value_list[0] != "*":
                    self.cursor.execute(sql, tuple(value_list))
                else:
                    self.cursor.execute(sql)
            else:
                self.cursor.execute(sql)
            result_list = self.cursor.fetchall()

            # 5.返回字典列表
            return [dict(zip(field_names_list, row)) for row in result_list]
        return inner
    return wrapper


class DBBase:

    def __init__(self, db_file_name: str = "blue2.0"):
        self.db_file_name = DB_ROOT_DIR + "/" + db_file_name + ".db"

    def __enter__(self, *args, **kwargs):
        self.conn = sqlite3.connect(self.db_file_name)
        self.cursor = self.conn.cursor()
        self.cursor.execute("PRAGMA foreign_keys = ON;")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type:
            self.conn.rollback()
        self.cursor.close()
        self.conn.close()
